package com.ktkj.init.controller;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.ktkj.init.response.Response;
import com.ktkj.init.response.ResponseCallBack;
import com.ktkj.init.response.ResponseCriteria;
import com.ktkj.init.service.ThreadPoolService;
import com.ktkj.init.service.component.RedisLock;
import com.ktkj.init.service.cx.ParentService;
import com.ktkj.init.task.utils.SpringUtils;
import com.ktkj.init.utils.MapUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;


/**
 * 测试管理.
 *
 * @author :yanlixiong
 * @date :2021-06-29 11:36:38
 */
@Slf4j
@Api(tags = "测试管理")
//@ApiIgnore
@RestController
@RequestMapping("/test")
public class TestController {

    @Resource
    private ThreadPoolService threadPoolService;

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private RedisLock redisLock;

    @Value("${server.port}")
    private String serverPort;

    @ApiOperation(value = "读取配置文件-获取server.port")
    @GetMapping(path = "/getServerPort")
    public Response getServerPort() {
        return new ResponseCallBack() {
            @Override
            public void execute(ResponseCriteria criteria, Object... obj) {
                criteria.addSingleResult(serverPort);
            }
        }.sendRequest();
    }

    @ApiOperation(value = "测试多线程")
    @GetMapping("/testThreadPool")
    public Response testThreadPool() {
        return new ResponseCallBack() {
            @Override
            public void execute(ResponseCriteria criteria, Object... obj) {
                log.info(">>>>>start.testThreadPool<<<<<");
                threadPoolService.sleep(3000);
                threadPoolService.sleep(4000);
                threadPoolService.sleep(5000);
                log.info(">>>>>end.testThreadPool<<<<<");
                criteria.addSingleResult(true);
            }
        }.sendRequest();
    }

    @ApiOperation(value = "测试Redis")
    @GetMapping("/testRedis")
    public String testRedis() {
        try {
            //redisTemplate.opsForValue(); //操作字符串
            redisTemplate.opsForValue().set("name", "张三");
            System.out.println("name|" + redisTemplate.opsForValue().get("name"));

            //redisTemplate.opsForHash(); //操作hash
            Map<String, Object> map = Maps.newHashMap();
            map.put("id", 1000);
            map.put("name", "张三");
            map.put("age", 18);
            map.put("sex", "男");
            redisTemplate.opsForHash().putAll("user:id:1000", map);
            System.out.println("user:id:1000|" + redisTemplate.opsForHash().entries("user:id:1000"));

            //redisTemplate.opsForList(); //操作list
            List<String> listData = Lists.newArrayList();
            listData.add("aa");
            listData.add("bb");
            listData.add("cc");
            listData.add("dd");
            redisTemplate.opsForList().leftPushAll("list:str", listData);
            redisTemplate.opsForList().leftPushAll("list:str", "ee");
            redisTemplate.opsForList().rightPush("list:str", "ff");
            System.out.println("list:str|" + redisTemplate.opsForList().range("list:str", 0, -1));
            System.out.println("list:str.size|" + redisTemplate.opsForList().size("list:str"));
            System.out.println("list:str.index=1|" + redisTemplate.opsForList().index("list:str", 1));

            //redisTemplate.opsForSet(); //操作set
            redisTemplate.opsForSet().add("set:str", "mm");
            redisTemplate.opsForSet().add("set:str", "aa");
            redisTemplate.opsForSet().add("set:str", "bb");
            redisTemplate.opsForSet().add("set:str", "cc");
            redisTemplate.opsForSet().add("set:str", "dd");
            redisTemplate.opsForSet().add("set:str", "ee");
            System.out.println("set:str|" + redisTemplate.opsForSet().members("set:str"));
            System.out.println("set:str.随机取值1|" + redisTemplate.opsForSet().randomMember("set:str"));
            System.out.println("set:str.随机取值2|" + redisTemplate.opsForSet().randomMember("set:str"));

            //redisTemplate.opsForZSet(); //操作有序set
            redisTemplate.opsForZSet().add("zset:str", "aa", 2);
            redisTemplate.opsForZSet().add("zset:str", "bb", 1);
            redisTemplate.opsForZSet().add("zset:str", "gg", 5);
            redisTemplate.opsForZSet().add("zset:str", "nn", 3);
            redisTemplate.opsForZSet().add("zset:str", "tt", 4);
            System.out.println("zset:str|" + redisTemplate.opsForZSet().range("zset:str", 0, -1));

            //expire 或者 set 设置过期时间
            /*redisTemplate.opsForValue().set("expire:5","嘻嘻");
            redisTemplate.expire("expire:5",5, TimeUnit.SECONDS);*/
            redisTemplate.opsForValue().set("expire:5", "嘻嘻", 5, TimeUnit.SECONDS);
            System.out.println("expire:5|未过期|" + redisTemplate.opsForValue().get("expire:5"));
            Thread.sleep(6000);
            System.out.println("expire:5|已过期|" + redisTemplate.opsForValue().get("expire:5"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "success";
    }

    @ApiOperation(value = "测试重复提交表单")
    @PostMapping("/testResubmitTheForm")
    public String createOrder(HttpServletRequest request, String name, Integer age) {
        //log.info("name={},age={}",name,age);
        String lockKey = MapUtils.getRedisKeyByParam(request.getParameterMap());
        log.info("lockKey={}", lockKey);
        if (redisLock.lock(lockKey)) {
            log.info("success");
            try {
                //处理业务逻辑
                Thread.sleep(2000L);
                redisLock.delete(lockKey);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "success";
        } else {
            log.info("请勿重复提交请求");
            return "请勿重复提交请求";
        }
    }

    @ApiOperation(value = "工厂模式+模板方法模式")
    @GetMapping("/testMS")
    public Response testMS(String key) {
        return new ResponseCallBack() {
            @Override
            public void execute(ResponseCriteria criteria, Object... obj) {
                ParentService parentService = (ParentService) SpringUtils.getBean(key + "Service");
                parentService.process(key);
                criteria.addSingleResult(true);
            }
        }.sendRequest();
    }

    @ApiOperation(value = "测试线程池中的所有线程都执行完")
    @GetMapping("/testThreads")
    public Response testThreads() {
        return new ResponseCallBack() {
            @Override
            public void execute(ResponseCriteria criteria, Object... obj) {
                threadPoolService.testThreads();
                criteria.addSingleResult(true);
            }
        }.sendRequest();
    }


}
